package universe;

import java.util.ArrayList;

public class Block{

	private  ArrayList<int[][]> matrix; 
	private  int currentPosition;

	private int width = 0;
	private int height = 0;


	public Block(ArrayList<int[][]> m){
		if(!m.isEmpty()){
			if(m.size() == Utils.getBlockHeight()){
				if(m.get(0).length == Utils.getBlockWidth() && m.get(1).length == Utils.getBlockWidth() && m.get(2).length == Utils.getBlockWidth() && m.get(3).length == Utils.getBlockWidth()){
					matrix = m;
					this.getSizes();
					//permet de générer une position initiale aléatoire entre 0 et 3
					currentPosition = (int) (Math.random() *4);
				}else System.err.println("pb taille : "+m.get(0).length);	
			}else System.err.println("Problème sur le nombre de positions du bloc");
		}else System.err.println("Attention la matrice pour le bloc est vide");
	}


	public Block(int[][] pMatrix){
		int [][] tmp;
		matrix = new ArrayList<int[][]>();
		matrix.add(pMatrix);
		currentPosition = 0;
		this.getSizes();

		tmp = this.getMinimalMatrix();
		matrix.remove(0);
		matrix.add(0,tmp);

		this.getSizes();

	}

	
	public void getSizes(){
		boolean exit = false;
		int UnUsedvalue;

		width = 0;
		height = 0;

		if(matrix.size() != 0){
			width = matrix.get(0).length;

			while (!exit){
				try{
					UnUsedvalue = matrix.get(0)[0][height];
					height++;
				}
				catch(Exception e){
					exit = true;
				}
			}
		}
	}



	@SuppressWarnings("unchecked")
	public Block(Block copyFrom){
		this.currentPosition = copyFrom.currentPosition;

		this.matrix = (ArrayList<int[][]>) copyFrom.matrix.clone();
	}

	public void rotate(){
		currentPosition = (currentPosition+1) %4;
	}

	public int[][] getMatrix(){
		return matrix.get(currentPosition);
	}


	/*public int[][] getMinimalMatrix(){
		int[][] minimalMatrix = new int[getWidth()][getHeight()];
		int nbEmptyLines = 0;
		int nbEmptyColumns = 0;
		boolean exit = false;

		// Calcul du nombre de colonnes vides avant la pièce
		for(int i = 0; i< Utils.BLOCK_WIDTH && !exit; i++){
			for(int j = 0; j< Utils.BLOCK_HEIGHT && !exit; j++){
				if(getCell(i, j) != 0){
					exit = true;
				}
			}
			nbEmptyColumns++;
		}
		nbEmptyColumns--;
		exit = false;


		// Calcul du nombre de lignes vides avant la pièce
		for(int j = 0; j< Utils.BLOCK_HEIGHT && !exit; j++){
			for(int i = 0; i< Utils.BLOCK_WIDTH && !exit; i++){
				if(getCell(i, j) != 0){
					exit = true;
				}
			}
				nbEmptyLines++;
		}
		nbEmptyLines--;



		for(int i = 0; i < getWidth() ; i++){
			for(int j = 0; j< getHeight() ; j++){
				minimalMatrix[i][j] = getCell(i + nbEmptyColumns, j + nbEmptyLines);
			}
		}

		return minimalMatrix;
	}*/
	public int[][] getMinimalMatrix(){
		int[][] minimalMatrix = new int[getMinimalWidth()][getMinimalHeight()];
		int nbEmptyLines = 0;
		int nbEmptyColumns = 0;
		boolean exit = false;

		// Calcul du nombre de colonnes vides avant la pièce
		for(int i = 0; i< width && !exit; i++){
			for(int j = 0; j< height && !exit; j++){
				if(getCell(i, j) != 0){
					exit = true;
				}
			}
			nbEmptyColumns++;
		}
		nbEmptyColumns--;
		exit = false;


		// Calcul du nombre de lignes vides avant la pièce
		for(int j = 0; j< height && !exit; j++){
			for(int i = 0; i< width && !exit; i++){
				if(getCell(i, j) != 0){
					exit = true;
				}
			}
			nbEmptyLines++;
		}
		nbEmptyLines--;



		for(int i = 0; i < getMinimalWidth() ; i++){
			for(int j = 0; j< getMinimalHeight() ; j++){
				minimalMatrix[i][j] = getCell(i + nbEmptyColumns, j + nbEmptyLines);
			}
		}

		return minimalMatrix;
	}

	// Test 
	public String toStringMinimal(){
		String retour="";

		int[][] matrix = this.getMinimalMatrix();
		for(int j=0; j< getMinimalHeight();j++){
			for(int i=0; i< getMinimalWidth();i++)
				retour = retour + String.valueOf(matrix[i][j]);

			retour = retour + "\n";
		}
		return retour;
	}





	public int getCell(int x, int y){
		return this.getMatrix()[x][y];
	}

	/*public int getWidth(){
		int size = 0;
		for(int i = 0; i< Utils.BLOCK_WIDTH; i++){
			for(int j = 0; j< Utils.BLOCK_HEIGHT; j++){
				if(getCell(i, j) != 0){
					size ++;
					break;
				}
			}
		}
		return size;
	}

	public int getHeight(){
		int size = 0;
		for(int j = 0; j< Utils.BLOCK_HEIGHT; j++){
			for(int i = 0; i< Utils.BLOCK_WIDTH; i++){
				if(getCell(i, j) != 0){
					size ++;
					break;
				}
			}
		}
		return size;
	}*/
	
	
	public int getHeight(){
		return height;
	}
	
	public int getWidth(){
		return width;
	}

	public int getMinimalWidth(){
		int size = 0;

		for(int i = 0; i< width; i++){
			for(int j = 0; j< height; j++){
				if(getCell(i, j) != 0){
					size ++;
					break;
				}
			}
		}
		return size;
	}

	public int getMinimalHeight(){
		int size = 0;
		for(int j = 0; j< height; j++){
			for(int i = 0; i< width; i++){
				if(getCell(i, j) != 0){
					size ++;
					break;
				}
			}
		}
		return size;
	}

	public int getCurrentPosition(){
		return currentPosition;
	}

	public void setCurrentPosition(int pCurrentPosition){
		this.currentPosition = pCurrentPosition;
	}

	public static Block getRandomBlock(){
		int rnd = (int) (Math.random() *7);

		switch (rnd){
		case 0: return new Block(Utils.getBlockA());
		case 1: return new Block(Utils.getBlockB());
		case 2: return new Block(Utils.getBlockC());
		case 3: return new Block(Utils.getBlockD());
		case 4: return new Block(Utils.getBlockE());
		case 5: return new Block(Utils.getBlockF());
		default: return new Block(Utils.getBlockG());
		}
	}

	//Utilisé pour les tests en mode console
	//NE DOIT PAS ETRE UTILISE POUR LE JEU
	public String toString(){
		String retour="";

		int[][] matrix = this.getMatrix();
		for(int j=0; j< height;j++){
			for(int i=0; i< width;i++){
				retour = retour + String.valueOf(matrix[i][j]);
			}
			retour = retour + "\n";
		}
		return retour;
	}

	public int getLowestLineIndex() {
		for(int line=Utils.getBlockHeight()-1; line>0; --line){
			for(int x=0; x<Utils.getBlockWidth(); ++x){
				if(this.getCell(x, line)!=0){
					return line;
				}
			}
		}
		return 0;
	}

	public int getRightmostColumnIndex() {
		for(int col = Utils.getBlockWidth()-1; col>0; --col){
			for(int y=0; y<Utils.getBlockHeight(); ++y){
				if(this.getCell(col, y)!=0){
					return col;
				}
			}
		}


		return 0;
	}

}
